package day18;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//测试 暴力反射
//总结:
//1, 普通反射 和 暴力反射 的区别 ?
    //暴力反射是可以获取public的甚至private
    //普通反射只能获取public的
//2, 怎么使用暴力反射?
    //用对API ( getDeclaredXxx() )
    //设置访问权限( setAccessible(true) )
//3, getDeclaredXxx() 和 getXxx() 的区别??
    //getXxx() 获取public资源 -- 获取自己的方法和父类的方法
    //getDeclaredXxx() 获取所有资源 --只获取自己的方法
public class Test3_Person {
    public static void main(String[] args) throws Exception {
//        method();//暴力反射 成员变量
        method2();//暴力反射 成员方法
    }
    //TODO 暴力反射成员方法
    public static void method2() throws Exception {
        Class c = Person.class;
        //暴力反射--获取所有方法
        Method[] ms = c.getDeclaredMethods();
        //遍历数组,获取每个方法m
        for (Method m : ms) {
            //获取方法名
            System.out.println(m.getName());
        }
        //TODO 获取指定的方法
        Method m = c.getDeclaredMethod("show");
        Object oo = c.newInstance();

        m.setAccessible(true);//开启 私有资源的 访问权限
        m.invoke(oo);
    }
    //TODO 暴力反射成员变量
    public static void method() throws Exception {
        Class c = Person.class;
        //暴力反射--获取所有属性,包括 public的private的default的
        Field[] fs = c.getDeclaredFields();
        //遍历数组,得到每个属性f
        for (Field f : fs) {
            //获取属性名
            System.out.println( f.getName() );
        }

        //只获取一个私有的属性
        Field f = c.getDeclaredField("name");
        Object o = c.newInstance();

        //对私有的属性操作抛出异常:IllegalAccessException
        f.setAccessible(true);//开启私有的访问权限
        f.set(o,"jack");//设置值
        System.out.println( f.get(o) );//获取值
    }
}
